# Project 9 Facial Expression LED Board ![image-20250510090912741](media/A87.png) ### **1.Description** How fun it is if a expression board is added to the robot. And the Keyestudio 8\*16 LED board can do the trick. With the help of it, you could design facial expressions, images, patterns and other displays by yourselves. The 8\*16 LED board comes with 128 LEDs. The data of the microprocessor(Arduino) communicates with the AiP1640 through a two-wire bus interface. Therefore, it can control the on and off of 128 LEDs on the module, so as to make the dot matrix on the module to display the pattern you need. A HX-2.54 4Pin cable is provided for your convenience of wiring. ### **2.Specification** - Working voltage: DC 3.3-5V - Power loss: 400mW - Oscillation frequency: 450KHz - Drive current: 200mA - Working temperature: -40\~80℃ - Communication mode: I2C ### **3.Circuit Diagram** ![image-20250510091309725](media/A88.png) ### **4.Working Principle** How to control each LED of the 8\*16 dot matrix? It is known that each byte has 8 bits and each bit is 0 or 1. when it is 0, LED is off while when it is 1 LED is on. One byte can control one column of the LED,and naturally 16 bytes can control 16 columns of LEDs, that’s the 8\*16 dot matrix. ### **5.Pins description and communication protocol** The data of the microprocessor (Arduino) communicates with the AiP1640 through a two-wire bus cable. The communication protocol diagram is as follows (SCLK) is SCL, (DIN) is SDA. ![image-20250510091407219](media/A89.png) ①The starting condition for data input: SCL is high level and SDA changes from high to low. ②For data command setting, there are methods as shown in the figure below. In our sample program, select the way to **add 1 to the address automatically**, the binary value is 0100 0000 and the corresponding hexadecimal value is 0x40. ![Img](media/A90.png) ③For address command setting, the address can be selected as shown below. The first 00H is selected in our sample program, and the binary number 1100 0000 corresponds to the hexadecimal 0xc0. ![Img](media/A91.png) ④The requirement for data input is that when SCL is at high level when inputting data, the signal on SDA must remain unchanged. Only when the clock signal on SCL is at low level, can the signal on SDA be changed. The input of data is the low bit first, and the high bit later. ⑤The condition for the end of data transmission is that when SCL is at low level, SDA at low level and SCL at high level, the level of SDA becomes high. ⑥Display control, set different pulse width, pulse width can be selected as shown in the figure below. In the example, the pulse width is 4/16, and the hexadecimal corresponding to 1000 1010 is 0x8A. ![Img](media/A92.png) **Instructions for the use of modulus tool** The dot matrix tool uses the online version, and the link is :[http://dotmatrixtool.com/\#](http://dotmatrixtool.com/\#) ①Enter the link and the page appears as shown below ![image-20250510091438524](media/A93.png) ②The dot matrix is 8\*16, so adjust the height to 8 and width to 16, as shown in the figure below. ![image-20250510091446519](media/A94.png) ③Generate hexadecimal data from the pattern As shown in the figure below, press the left mouse button to select, right click to cancel; draw the pattern you want, click Generate, and the hexadecimal data we need will be generated. ![image-20250510091457463](media/A95.png) ### **6.Components** | Development Board *1 | 8833 Motor Driver *1 | USB Cable*1 | | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------- | | ![img](media/A80.jpg) | ![img](media/A81.jpg) | ![img](media/A82.jpg) | | USB Cable*1 | HX-2.54 4P Dupont Wire 200mm *1 | | | ![image-20250512155818434](media/A96.png) | ![image-20250512155822969](media/A97.png) | | ### **7.Wiring Diagram** ![cec50fec4a335b6922e4c6694a133bc1](media/A98.png) The GND, VCC, SDA, and SCL of the 8x16 LED light board are respectively connected to the keyestudio sensor expansion board-(GND), + (VCC), A4, A5 for two-wire serial communication. (Note: Though it is connected with the IIC pin of Arduino, this module is not for IIC communication. And the IO port here is to simulate I2C communication and can be connected with any two pins ). ### **8.Test Code** The code will show the smile face. ```c //************************************************************************ /* keyestudio 4wd BT Car lesson 9.1 Matrix face http://www.keyestudio.com */ //Data from the smile pattern obtained from the touch tool unsigned char smile[] = {0x00, 0x00, 0x1c, 0x02, 0x02, 0x02, 0x5c, 0x40, 0x40, 0x5c, 0x02, 0x02, 0x02, 0x1c, 0x00, 0x00}; #define SCL_Pin A5 //Set the clock pin to A5 #define SDA_Pin A4 //Set data pin to A4 void setup() { //Set pin to output pinMode(SCL_Pin, OUTPUT); pinMode(SDA_Pin, OUTPUT); //clear //matrix_display(clear); } void loop() { matrix_display(smile); //display smiling expression pattern } //this function is used for dot matrix display void matrix_display(unsigned char matrix_value[]) { IIC_start(); //the function that calls the data transfer start condition IIC_send(0xc0); //select address for (int i = 0; i < 16; i++) //the pattern data is 16 bytes { IIC_send(matrix_value[i]); //Transmit the data of the pattern } IIC_end(); //End pattern data transmission IIC_start(); IIC_send(0x8A); //Display control, select 4/16 pulse width IIC_end(); } //Conditions under which data transmission begins void IIC_start() { digitalWrite(SDA_Pin, HIGH); digitalWrite(SCL_Pin, HIGH); delayMicroseconds(3); digitalWrite(SDA_Pin, LOW); delayMicroseconds(3); digitalWrite(SCL_Pin, LOW); } //Indicates the end of data transmission void IIC_end() { digitalWrite(SCL_Pin, LOW); digitalWrite(SDA_Pin, LOW); delayMicroseconds(3); digitalWrite(SCL_Pin, HIGH); delayMicroseconds(3); digitalWrite(SDA_Pin, HIGH); delayMicroseconds(3); } //transmit data void IIC_send(unsigned char send_data) { for (byte mask = 0x01; mask != 0; mask <<= 1) //Each byte has 8 bits and is checked bit by bit starting at the lowest level { if (send_data & mask) { //Sets the high and low levels of SDA_Pin depending on whether each bit of the byte is a 1 or a 0 digitalWrite(SDA_Pin, HIGH); } else { digitalWrite(SDA_Pin, LOW); } delayMicroseconds(3); digitalWrite(SCL_Pin, HIGH); //Pull the clock pin SCL_Pin high to stop data transmission delayMicroseconds(3); digitalWrite(SCL_Pin, LOW); //pull the clock pin SCL_Pin low to change the SIGNAL of SDA } } //************************************************************************ ``` ### **9.Test Result** After successfully uploading the code to the V4.0 board, connect the wirings according to the wiring diagram, then turn the DIP switch to ON, a smile-shaped pattern will be displayed on the LED board. ![95bb011957896b12285fc6763137bb9a](media/A99.png) ### **10.Code Explanation** We use the modulus tool we just learned, [http://dotmatrixtool.com/\#](http://dotmatrixtool.com/\#), to make the dot matrix display the start pattern, going forward, and stop and then clear the pattern. The time interval is 2000 ms. ![image-20250512155957415](media/A100.png)![image-20250512160002378](media/A101.png)![image-20250512160006841](media/A102.png)![image-20250512160010543](media/A103.png) **Code obtained from the module tool:** **Code for the pattern start:** 0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01 **Code for the pattern going forward:** 0x00,0x00,0x00,0x00,0x00,0x24,0x12,0x09,0x12,0x24,0x00,0x00,0x00,0x00,0x00,0x00 **Code for the pattern stepping back:** 0x00,0x00,0x00,0x00,0x00,0x24,0x48,0x90,0x48,0x24,0x00,0x00,0x00,0x00,0x00,0x00 **Code for the pattern turning left:** 0x00,0x00,0x00,0x00,0x00,0x00,0x44,0x28,0x10,0x44,0x28,0x10,0x44,0x28,0x10,0x00 **Code for the pattern turning right:** 0x00,0x10,0x28,0x44,0x10,0x28,0x44,0x10,0x28,0x44,0x00,0x00,0x00,0x00,0x00,0x00 **Code for the pattern stop:** 0x2E,0x2A,0x3A,0x00,0x02,0x3E,0x02,0x00,0x3E,0x22,0x3E,0x00,0x3E,0x0A,0x0E,0x00 **Code to clear screen:** 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ![cec50fec4a335b6922e4c6694a133bc1](media/A104.png) ```c //************************************************************************ /* keyestudio 4wd BT Car lesson 9.2 Matrix face http://www.keyestudio.com */ //Data from the smile pattern obtained from the touch tool unsigned char start01[] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01}; unsigned char front[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x12, 0x09, 0x12, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; unsigned char back[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x48, 0x90, 0x48, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; unsigned char left[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x28, 0x10, 0x44, 0x28, 0x10, 0x44, 0x28, 0x10, 0x00}; unsigned char right[] = {0x00, 0x10, 0x28, 0x44, 0x10, 0x28, 0x44, 0x10, 0x28, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; unsigned char STOP01[] = {0x2E, 0x2A, 0x3A, 0x00, 0x02, 0x3E, 0x02, 0x00, 0x3E, 0x22, 0x3E, 0x00, 0x3E, 0x0A, 0x0E, 0x00}; unsigned char clear[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; #define SCL_Pin A5 //Set the clock pin to A5 #define SDA_Pin A4 //Set data pin to A4 void setup() { //Set pin to output pinMode(SCL_Pin, OUTPUT); pinMode(SDA_Pin, OUTPUT); //clear //matrix_display(clear); } void loop() { matrix_display(start01); //Show start pattern delay(2000); matrix_display(front); //Show forward pattern delay(2000); matrix_display(STOP01); //Show stop pattern delay(2000); matrix_display(clear); //Clear Screen delay(2000); } //this function is used for dot matrix display void matrix_display(unsigned char matrix_value[]) { IIC_start(); //the function that calls the data transfer start condition IIC_send(0xc0); //select address for (int i = 0; i < 16; i++) //the pattern data is 16 bytes { IIC_send(matrix_value[i]); //Transmit the data of the pattern } IIC_end(); //End pattern data transmission IIC_start(); IIC_send(0x8A); //Display control, select 4/16 pulse width IIC_end(); } //Conditions under which data transmission begins void IIC_start() { digitalWrite(SDA_Pin, HIGH); digitalWrite(SCL_Pin, HIGH); delayMicroseconds(3); digitalWrite(SDA_Pin, LOW); delayMicroseconds(3); digitalWrite(SCL_Pin, LOW); } //Indicates the end of data transmission void IIC_end() { digitalWrite(SCL_Pin, LOW); digitalWrite(SDA_Pin, LOW); delayMicroseconds(3); digitalWrite(SCL_Pin, HIGH); delayMicroseconds(3); digitalWrite(SDA_Pin, HIGH); delayMicroseconds(3); } //transmit data void IIC_send(unsigned char send_data) { for (byte mask = 0x01; mask != 0; mask <<= 1) //Each byte has 8 bits and is checked bit by bit starting at the lowest level { if (send_data & mask) { //Sets the high and low levels of SDA_Pin depending on whether each bit of the byte is a 1 or a 0 digitalWrite(SDA_Pin, HIGH); } else { digitalWrite(SDA_Pin, LOW); } delayMicroseconds(3); digitalWrite(SCL_Pin, HIGH); //Pull the clock pin SCL_Pin high to stop data transmission delayMicroseconds(3); digitalWrite(SCL_Pin, LOW); //pull the clock pin SCL_Pin low to change the SIGNAL of SDA } } //************************************************************************ ``` After uploading test code, the facial expression board shows these patterns orderly and repeats this sequence. ![image-20250512160131674](media/A105.png)![image-20250512160135717](media/A106.png)![image-20250512160139283](media/A107.png)